home *** CD-ROM | disk | FTP | other *** search
Modula Implementation | 1994-03-17 | 7.8 KB | 223 lines |
- IMPLEMENTATION MODULE IPF;
-
- FROM SYSTEM IMPORT TSIZE, BYTE, WORD, LONGWORD;
- FROM Storage IMPORT ALLOCATE, DEALLOCATE;
- IMPORT Str, Err, DiskIO, Lib, IO;
-
- TYPE
- aFileOfs = LONGCARD;
- aFileLength = LONGCARD;
-
- (*-------------------------------------------------- header *)
-
- TYPE
- aHeader = RECORD
- ID: CARDINAL; (* magic "HS" *)
- unknown1: BYTE;
- flags: BYTESET; (* says .INF or .HLP *)
- headerSize: aLength; (* total size of header *)
- unknown2: WORD;
- tocCnt: aCount; (* no of entries in table-of-contents *)
- tocStrStart: aFileOfs; (* table of toc strings *)
- tocStrLen: aFileLength;
- tocStart: aFileOfs; (* array of aTocEntryRef *)
- resCnt: aCount; (* no of panels with resource nos *)
- resStart: aFileOfs; (* resource number table *)
- nameCnt: aCount; (* no of panels with names *)
- nameStart: aFileOfs; (* panel name table *)
- idxCnt: aCount; (* no of index entries *)
- idxStart: aFileOfs; (* index table *)
- idxLen: aFileLength;
- unknown3: ARRAY [1..10] OF BYTE;
- searchStart: aFileOfs; (* start of full-text search table *)
- searchLen: aFileLength;
- slotCnt: aCount; (* number of slots *)
- slotStart: aFileOfs; (* slot table *)
- dictLen: aFileLength; (* length of dictionary *)
- dictCnt: aCount; (* no of entries in dictionary *)
- dictStart: aFileOfs; (* start of dictionary *)
- imgStart: aFileOfs; (* start of image data *)
- unknown4: BYTE;
- nlsStart: aFileOfs; (* NLS data *)
- nlsLen: aFileLength;
- extStart: aFileOfs; (* extended block *)
- unknown5: ARRAY [1..12] OF BYTE;
- title: ARRAY [0..47] OF CHAR; (* title of document *)
- END;
-
- VAR
- Input: DiskIO.aFile;
- Header: aHeader;
-
- (*-------------------------------------------------- references *)
-
- TYPE
- aRef = POINTER TO ARRAY anIndex OF aFileOfs;
-
- PROCEDURE ReadRef (VAR r: aRef; at: aFileOfs; cnt: aCount);
- BEGIN
- ALLOCATE( r, cnt * TSIZE(aFileOfs) );
- DiskIO.MoveTo( Input, at );
- DiskIO.ReadBlock( Input, r^, cnt * TSIZE(aFileOfs) );
- END ReadRef;
-
- (*-------------------------------------------------- table-of-contents *)
-
- PROCEDURE ReadToc;
- VAR
- toc: aRef;
- i: anIndex;
- e: aTocPtr;
- ll: SHORTCARD;
- l: aLength;
- skip: aLength;
- w1,w2: BYTESET;
- BEGIN
- IO.WrLn; IO.WrStr( "Reading " ); IO.WrCard( Header.tocCnt,0 );
- IO.WrStr( " table-of-contents entries..." );
- TocCnt:= Header.tocCnt;
- ReadRef( toc, Header.tocStart, Header.tocCnt );
- ALLOCATE( Toc, Header.tocCnt * TSIZE(ADDRESS) );
- FOR i:= 0 TO Header.tocCnt-1 DO
- NEW( Toc^[i] );
- WITH Toc^[i]^ DO
- DiskIO.MoveTo( Input, toc^[i] );
- DiskIO.Read( Input, ll ); l:= VAL(CARDINAL,ll);
- DiskIO.Read( Input, flags );
- nest:= VAL(CARDINAL, SHORTCARD(flags) MOD 16 );
- DiskIO.Read( Input, ll ); slotCnt:= VAL(aCount,ll);
- ALLOCATE( slot, slotCnt * TSIZE(anIndex) );
- IF Extended IN flags THEN
- DiskIO.Read( Input, w1 );
- DiskIO.Read( Input, w2 );
- skip:= 0;
- IF 0 IN w1 THEN INC(skip,5) END;
- IF 1 IN w1 THEN INC(skip,5) END;
- IF 3 IN w1 THEN INC(skip,2) END;
- IF 2 IN w2 THEN INC(skip,2) END;
- DiskIO.MoveTo( Input, DiskIO.Pos(Input) + VAL(LONGCARD,skip) );
- END;
- DiskIO.ReadBlock( Input, slot^, slotCnt * TSIZE(anIndex) );
- l:= l - VAL(INTEGER, DiskIO.Pos(Input) - toc^[i] );
- ALLOCATE( title, l+1 );
- DiskIO.ReadBlock( Input, title^, l );
- title^[l]:= 0C;
- END;
- END;
- DEALLOCATE( toc, Header.tocCnt * TSIZE(aFileOfs) );
- END ReadToc;
-
-
- (*-------------------------------------------------- index *)
-
- PROCEDURE ReadIdx;
- VAR
- i: anIndex;
- l: aLength;
- ll: SHORTCARD;
- BEGIN
- IO.WrLn; IO.WrStr( "Reading " ); IO.WrCard( Header.idxCnt,0 );
- IO.WrStr( " index entries..." );
- IdxCnt:= Header.idxCnt;
- IF Header.idxCnt = 0 THEN RETURN END;
- DiskIO.MoveTo( Input, Header.idxStart );
- ALLOCATE( Idx, Header.idxCnt * TSIZE(anIdxEntry) );
- FOR i:= 0 TO Header.idxCnt-1 DO
- NEW( Idx^[i] );
- WITH Idx^[i]^ DO
- DiskIO.Read( Input, ll ); l:= VAL(CARDINAL,ll);
- DiskIO.Read( Input, ll ); level:= VAL(CARDINAL,ll);
- DiskIO.Read( Input, ll );
- DiskIO.Read( Input, toc );
- ALLOCATE( name, l+1 );
- DiskIO.ReadBlock( Input, name^, l );
- name^[l]:= 0C;
- END;
- END;
- END ReadIdx;
-
-
- (*-------------------------------------------------- dictionary *)
-
- VAR
- DictWords: POINTER TO ARRAY [0..65530] OF CHAR;
-
- PROCEDURE ReadDict;
- VAR
- i: anIndex;
- p, pp: CARDINAL;
- BEGIN
- IO.WrLn; IO.WrStr( "Reading " ); IO.WrCard( Header.dictCnt,0 );
- IO.WrStr( " dictionary entries..." );
- DictCnt:= Header.dictCnt;
- ALLOCATE( Dict, Header.dictCnt * TSIZE(ADDRESS) );
- ALLOCATE( DictWords, VAL(CARDINAL,Header.dictLen) + 1);
- DiskIO.MoveTo( Input, Header.dictStart );
- DiskIO.ReadBlock( Input, DictWords^, VAL(CARDINAL,Header.dictLen) );
- DictWords^[VAL(CARDINAL,Header.dictLen)]:= 0C;
- p:= 0;
- FOR i:= 0 TO Header.dictCnt-1 DO
- Dict^[i]:= ADR(DictWords^[p+1]);
- pp:= p + VAL(CARDINAL, SHORTCARD(DictWords^[p]) );
- DictWords^[p]:= 0C;
- p:= pp;
- END;
- END ReadDict;
-
- (*-------------------------------------------------- slots *)
-
- PROCEDURE ReadSlots;
- VAR
- ofs: aRef;
- localOfs: aFileOfs;
- i: anIndex;
- stuff: BYTE;
- BEGIN
- IO.WrLn; IO.WrStr( "Reading " ); IO.WrCard( Header.slotCnt,0 );
- IO.WrStr( " slots..." );
- SlotCnt:= Header.slotCnt;
- ALLOCATE( Slot, Header.slotCnt * TSIZE(ADDRESS) );
- ReadRef( ofs, Header.slotStart, Header.slotCnt );
- FOR i:= 0 TO Header.slotCnt-1 DO
- NEW(Slot^[i]);
- WITH Slot^[i]^ DO
- DiskIO.MoveTo( Input, ofs^[i] );
- DiskIO.Read( Input, stuff );
- DiskIO.Read( Input, localOfs );
- DiskIO.Read( Input, localCnt );
- DiskIO.Read( Input, textCnt );
- ALLOCATE( text, textCnt * TSIZE(aWord) );
- DiskIO.ReadBlock( Input, text^, textCnt * TSIZE(aWord) );
- ALLOCATE( local, VAL(CARDINAL,localCnt) * TSIZE(anIndex) );
- DiskIO.MoveTo( Input, localOfs );
- DiskIO.ReadBlock( Input, local^, VAL(CARDINAL,localCnt) * TSIZE(anIndex) );
- END;
- END;
- DEALLOCATE( ofs, Header.slotCnt * TSIZE(aFileOfs) );
- END ReadSlots;
-
- (*-------------------------------------------------- globals *)
-
- PROCEDURE Open (fname: ARRAY OF CHAR);
- BEGIN
- IF DiskIO.Open( Input, fname ) THEN
- DiskIO.Read( Input, Header );
- Str.Assign( Title, Header.title );
- IO.WrStr( Title );
- ReadToc;
- ReadIdx;
- ReadDict;
- ReadSlots;
- ELSE
- Err.Fatal( "Cannot open .INF file." );
- END;
- END Open;
-
- PROCEDURE Close;
- BEGIN
- DiskIO.Close( Input );
- END Close;
-
-
- END IPF.